package com.mi.system.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mi.system.entity.RoleMenu;
import com.mi.system.mapper.RoleMenuMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Role menu service
 *
 * @author jin_huaquan
 * @version 1.0
 * @date 2021/11/1 14:03
 */
@Service
@RequiredArgsConstructor
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements RoleMenuService {

    @Override
    public List<String> listMenuId(Long roleId) {
        List<RoleMenu> roleMenus = baseMapper.selectList(Wrappers.<RoleMenu>lambdaQuery()
                .eq(RoleMenu::getRoleId, roleId));

        return roleMenus.stream()
                .map(roleMenu -> roleMenu.getMenuId().toString())
                .collect(Collectors.toList());
    }

    @Override
    public List<String> listMenuPermission(Long[] roleIds) {
        return baseMapper.selectPermissionByRoleIds(roleIds);
    }

    @Override
    public boolean saveRoleMenu(Long[] menuIds, Long roleId) {
        List<RoleMenu> roleMenuList = Arrays.stream(menuIds)
                .map(menuId -> setRoleMenu(roleId, menuId))
                .collect(Collectors.toList());

        return this.saveBatch(roleMenuList);
    }

    @Override
    public boolean updateRoleMenu(Long[] menuIds, Long roleId) {
        List<RoleMenu> roleMenuList = this.list(Wrappers.<RoleMenu>lambdaQuery().eq(RoleMenu::getRoleId, roleId));
        List<Long> removingMenuIdList = roleMenuList.stream()
                .filter(roleMenu -> Arrays.stream(menuIds).noneMatch(menuId -> Objects.equals(menuId, roleMenu.getMenuId())))
                .map(RoleMenu::getMenuId)
                .collect(Collectors.toList());

        List<RoleMenu> savingRoleMenuList = Arrays.stream(menuIds)
                .filter(menuId -> roleMenuList.stream().noneMatch(roleMenu -> Objects.equals(roleMenu.getMenuId(), menuId)))
                .map(menuId -> setRoleMenu(roleId, menuId))
                .collect(Collectors.toList());

        if (!removingMenuIdList.isEmpty()) {
            this.remove(Wrappers.<RoleMenu>lambdaQuery().and(i -> i.eq(RoleMenu::getRoleId, roleId).in(RoleMenu::getMenuId, removingMenuIdList)));
        }
        if (!savingRoleMenuList.isEmpty()) {
            this.saveBatch(savingRoleMenuList);
        }

        return true;
    }

    @Override
    public boolean removeRoleMenu(Long roleId) {
        return this.remove(Wrappers.<RoleMenu>lambdaQuery().eq(RoleMenu::getRoleId, roleId));
    }

    /**
     * set role menu
     *
     * @param roleId Role ID
     * @param menuId Menu ID
     * @return role menu
     */
    private RoleMenu setRoleMenu(Long roleId, Long menuId) {
        RoleMenu roleMenu = new RoleMenu();

        roleMenu.setRoleId(roleId);
        roleMenu.setMenuId(menuId);

        return roleMenu;
    }
}
